﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI.WebControls;
using Medianamik.Core;
using Medianamik.Core.DAL.Repositories;
using Medianamik.Core.Profile;
using Medianamik.Core.Security;
using Medianamik.Globalization;
using Medianamik.UI.Controls;
using Medianamik.UI.Web.Membership.Views;
using Medianamik.UI.Web.MVP.Presentation;
using Telerik.Web.UI;
using Medianamik.Core.Sugar;

namespace Medianamik.UI.Web.Membership.Presenters
{
    public class UserListPresenter<T> : ModulePresenterWithGrid<T, IUserList,
        IUserProfileRepository<T>, INodeTypeRepository, IMedianamikRepository<IMedianamikDTOWithName>>
        where T : class, IUserProfile
    {
        public UserListPresenter(IUserList view, IUserProfileRepository<T> userProfileRepository,
            INodeTypeRepository nodeTypeRepository, IMedianamikRepository<IMedianamikDTOWithName> baseTypeRepository)
            : base(view, userProfileRepository, nodeTypeRepository, baseTypeRepository)
        {

        }

        protected override void Initialize(object sender, EventArgs e)
        {
            base.Initialize(sender, e);

            if (!View.IsPostBack)
            {
                BindGroups(Group);
            }
        }

        protected override Core.DAL.PagedCollection<T> GetData()
        {
            var group = String.IsNullOrEmpty(Group)
                            ? GetAllAllowedGroupNames()
                            : Group;

            return Repository.PagedWithFilters(PageIndex, PageSize,
                group, Keywords, (ActiveStatus)Status);
        }

        protected virtual string GetAllAllowedGroupNames()
        {
            return View.MedianamikUser.IsSuperAdmin ? null :
                GetAllAllowedGroups().Select(g => g.Name).ToString(",");
        }

        protected override void SetCustomGridColumns(GridItem item, T element,
            bool existInCurrentCulture)
        {
            base.SetCustomGridColumns(item, element, existInCurrentCulture);

            var profile = element as UserProfile;

            if (profile != null && profile.UserName.EqualsIgnoreCase(View.MedianamikUser.UserName))
            {
                UserCannotEditHimself(item, profile);
                UserCannotDeleteHimself(item, profile);
            }
        }

        //Dépend de peut gérer son propre groupe ?
        protected virtual void UserCannotEditHimself(GridItem item, UserProfile profile)
        {
            var editButton = (LockButton)item.FindControl("EditButton");
            editButton.Enabled = profile.MayManageOwnGroup;
        }

        protected virtual void UserCannotDeleteHimself(GridItem item, UserProfile profile)
        {
            var deleteButton = (LockButton)item.FindControl("DeleteButton");
            deleteButton.Enabled = false;
        }

        #region Groups

        private bool _selectedGroupIsRetreived;
        private string GetSelectedGroup()
        {
            if (View.Groups == null)
                return null;

            _selectedGroupIsRetreived = true;
            var selectedTheme = View.Groups.FirstOrDefault(i => i.Selected) ??
                                View.Groups.FirstOrDefault();

            string group = null;

            if (selectedTheme != null && !String.IsNullOrEmpty(selectedTheme.Value))
                group = selectedTheme.Value;

            return group;
        }
        private string _selectedGroup;
        private string _group;
        protected virtual string SelectedGroup
        {
            get
            {
                if (_selectedGroupIsRetreived)
                    return _selectedGroup;

                return _selectedGroup = GetSelectedGroup();
            }
        }
        protected virtual void BindGroups(string selectedGroup)
        {
            var options = new List<ListItem> { new ListItem(Translator.Translate("Medianamik_SecurityManagement", "AllUsers"), "") }
                .Union(GetAllAllowedGroups().Select(g => new ListItem(g.TranslatedName, g.Name))).ToArray();

            if (selectedGroup != null)
            {
                options.First(i => i.Value.Equals(selectedGroup)).Selected = true;
            }

            View.Groups = options;
        }
        protected virtual string Group
        {
            get
            {
                return _group ?? (_group = GetGroup()) ?? DefaultGroup;
            }
        }
        protected virtual string GetGroup()
        {
            return View.IsPostBack ? SelectedGroup : View.QueryString.GetValue<string>("group");
        }
        protected virtual string DefaultGroup
        {
            get
            {
                return "";
            }
        }

        protected virtual List<Group> GetAllAllowedGroups()
        {
            var allAllowedGroups = View.MedianamikUser.Groups.GetAllAllowedGroups(View.MedianamikUserProfile).ToList();

            if (allAllowedGroups.Count > 0)
            {
                allAllowedGroups.RemoveAll(g =>
                    GroupsToExclude.Any(groupsToExclude => groupsToExclude.EqualsIgnoreCase(g.Name)));
            }

            return allAllowedGroups;
        }

        static readonly List<string> ExcludedGroups = new List<string>();
        protected virtual List<string> GroupsToExclude
        {
            get { return ExcludedGroups; }
        }

        protected override string TypeSelectorUrl
        {
            get
            {
                if (GroupsToExclude.Count > 0)
                {
                    return base.TypeSelectorUrl.AddParam(DefaultParamNames.GroupsToExclude,
                        GroupsToExclude.ToString(",").EncodeBase64());
                }

                return base.TypeSelectorUrl;
            }
        }

        #endregion
    }
}
